package com.yc.testupload.util;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

/**
 * 环境配置管理类
 * 用于管理和切换不同环境的数据库配置
 */
public class EnvironmentManager {
    private static final Logger logger = LogManager.getLogger(EnvironmentManager.class);
    private static final EnvironmentManager instance = new EnvironmentManager();

    // 环境常量
    public static final String ENVIRONMENT_TEST = "test";
    public static final String ENVIRONMENT_PROD = "prod";

    // 配置文件路径常量
    private static final String CONFIG_FILE_PREFIX = "database-";
    private static final String CONFIG_FILE_SUFFIX = ".properties";
    private static final String CURRENT_ENV_CONFIG_FILE = "environment.properties";

    // 当前环境
    private String currentEnvironment;

    // 私有构造函数
    private EnvironmentManager() {
        // 初始化当前环境
        initCurrentEnvironment();
    }

    /**
     * 获取单例实例
     */
    public static EnvironmentManager getInstance() {
        return instance;
    }

    /**
     * 初始化当前环境
     */
    private void initCurrentEnvironment() {
        try (InputStream input = EnvironmentManager.class.getClassLoader()
                .getResourceAsStream(CURRENT_ENV_CONFIG_FILE)) {
            if (input != null) {
                Properties properties = new Properties();
                properties.load(input);
                currentEnvironment = properties.getProperty("current.environment", ENVIRONMENT_TEST);
                logger.info("初始化环境成功，当前环境: {}", currentEnvironment);
            } else {
                // 如果没有环境配置文件，默认使用测试环境
                currentEnvironment = ENVIRONMENT_TEST;
                saveCurrentEnvironment(currentEnvironment);
                logger.info("环境配置文件不存在，默认使用测试环境，并创建配置文件");
            }
        } catch (IOException e) {
            // 异常情况下默认使用测试环境
            currentEnvironment = ENVIRONMENT_TEST;
            logger.error("初始化环境失败，默认使用测试环境: {}", e.getMessage());
        }
    }

    /**
     * 获取当前环境
     */
    public String getCurrentEnvironment() {
        return currentEnvironment;
    }

    /**
     * 切换环境
     * 
     * @param environment 目标环境
     * @return 是否切换成功
     */
    public boolean switchEnvironment(String environment) {
        if (!ENVIRONMENT_TEST.equals(environment) && !ENVIRONMENT_PROD.equals(environment)) {
            logger.error("无效的环境类型: {}", environment);
            return false;
        }

        if (environment.equals(currentEnvironment)) {
            logger.info("已经是{}环境，重新加载配置以确保最新", environment);
            // 即使是同一环境，也重新加载配置以确保配置最新
            DatabaseUtil.reloadConfiguration();
            return true;
        }

        logger.info("开始切换环境: {} -> {}", currentEnvironment, environment);

        // 直接更新内存中的当前环境，不再依赖保存到文件
        currentEnvironment = environment;
        logger.info("环境已更新为: {}", currentEnvironment);

        // 重新加载配置
        DatabaseUtil.reloadConfiguration();
        logger.info("配置重新加载完成，环境切换成功");

        return true;
    }

    /**
     * 保存当前环境配置
     */
    private boolean saveCurrentEnvironment(String environment) {
        try {
            // 创建properties对象
            Properties properties = new Properties();
            properties.setProperty("current.environment", environment);

            // 获取配置文件路径
            // 当应用程序在JAR包中运行时，避免使用URL.getPath()方法（在Windows上可能包含特殊字符）
            // 而是直接保存到当前工作目录下的resources文件夹
            String configPath = System.getProperty("user.dir") + System.getProperty("file.separator") + "src"
                    + System.getProperty("file.separator") + "main" + System.getProperty("file.separator") + "resources"
                    + System.getProperty("file.separator") + CURRENT_ENV_CONFIG_FILE;

            // 保存到文件系统
            java.io.File file = new java.io.File(configPath);
            if (!file.exists()) {
                // 创建父目录
                file.getParentFile().mkdirs();
                // 创建文件
                file.createNewFile();
            }

            try (java.io.FileOutputStream output = new java.io.FileOutputStream(file)) {
                properties.store(output, "环境配置");
                return true;
            }
        } catch (IOException e) {
            logger.error("保存环境配置失败: {}", e.getMessage());
            return false;
        }
    }

    /**
     * 获取当前环境的数据库配置文件路径
     */
    public String getDatabaseConfigFilePath() {
        return CONFIG_FILE_PREFIX + currentEnvironment + CONFIG_FILE_SUFFIX;
    }

    /**
     * 获取指定环境的数据库配置
     * 
     * @param environment 环境名称
     * @return 配置Properties对象
     */
    public Properties getDatabaseConfig(String environment) {
        Properties properties = new Properties();
        String configPath = CONFIG_FILE_PREFIX + environment + CONFIG_FILE_SUFFIX;

        logger.info("尝试加载配置文件: {}, 当前环境: {}", configPath, environment);

        // 优先从文件系统加载 - 确保获取最新的配置
        // 这是最优先的，因为用户通过界面保存的配置会保存在这里
        boolean loaded = false;
        try {
            String filePath = System.getProperty("user.dir") + File.separator + configPath;
            File configFile = new File(filePath);
            if (configFile.exists()) {
                try (InputStream input = new FileInputStream(configFile)) {
                    properties.load(input);
                    logger.info("成功从文件系统加载{}环境的数据库配置，配置项数量: {}", environment, properties.size());
                    loaded = true;
                }
            } else {
                logger.info("文件系统中不存在{}环境的数据库配置文件: {}", environment, filePath);
            }
        } catch (IOException e) {
            logger.error("从文件系统加载{}环境的数据库配置文件失败: {}", environment, e.getMessage());
        }

        // 如果文件系统加载失败，尝试从类路径加载（适用于JAR包运行环境）
        if (!loaded) {
            try (InputStream input = getClass().getClassLoader().getResourceAsStream(configPath)) {
                if (input != null) {
                    properties.load(input);
                    logger.info("成功从类路径加载{}环境的数据库配置，配置项数量: {}", environment, properties.size());
                    loaded = true;
                } else {
                    logger.warn("类路径中找不到{}环境的数据库配置文件: {}", environment, configPath);
                }
            } catch (IOException e) {
                logger.error("从类路径加载{}环境的数据库配置文件失败: {}", environment, e.getMessage());
            }
        }

        // 如果类路径加载失败，尝试从src/main/resources目录加载（开发环境）
        if (!loaded) {
            String filePath = System.getProperty("user.dir") + System.getProperty("file.separator") +
                    "src" + System.getProperty("file.separator") + "main" + System.getProperty("file.separator") +
                    "resources" + System.getProperty("file.separator") + configPath;

            logger.info("尝试从开发目录加载: {}", filePath);
            try (InputStream input = new java.io.FileInputStream(filePath)) {
                properties.load(input);
                logger.info("成功从开发目录加载{}环境的数据库配置，配置项数量: {}", environment, properties.size());
                loaded = true;
            } catch (IOException e) {
                logger.error("找不到{}环境的数据库配置文件: {}，错误: {}", environment, filePath, e.getMessage());
            }
        }

        // 如果配置加载失败且是空的，尝试创建默认配置
        if (!loaded && properties.isEmpty()) {
            logger.error("无法加载{}环境的配置，使用默认配置！这可能会导致连接失败", environment);
            // 设置一些基本默认值，确保至少有一些配置
            if (ENVIRONMENT_TEST.equals(environment)) {
                // 使用与配置文件相同的默认值，而不是root无密码
                properties.setProperty("jdbc.driver", "com.mysql.cj.jdbc.Driver");
                properties.setProperty("jdbc.url",
                        "jdbc:mysql://115.159.219.140:3306/testdidadoc2?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai");
                properties.setProperty("jdbc.username", "testdidadoc2");
                properties.setProperty("jdbc.password", "PfiyxdTSAG2iPpma");
                properties.setProperty("jdbc.initialSize", "5");
                properties.setProperty("jdbc.maxActive", "20");
                properties.setProperty("jdbc.maxIdle", "10");
                properties.setProperty("jdbc.minIdle", "5");
                properties.setProperty("image.analysis.api", "http://127.0.0.1:50000");
            }
        }

        return properties;
    }

    /**
     * 获取当前环境的数据库配置
     */
    public Properties getCurrentDatabaseConfig() {
        return getDatabaseConfig(currentEnvironment);
    }
}